| Conditions | 37 |
| Total Lines | 267 |
| Code Lines | 182 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like clockpicker.js ➔ ClockPicker often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | /*! |
||
| 90 | function ClockPicker(element, options) { |
||
| 91 | var popover = $(tpl), |
||
| 92 | plate = popover.find('.clockpicker-plate'), |
||
| 93 | hoursView = popover.find('.clockpicker-hours'), |
||
| 94 | minutesView = popover.find('.clockpicker-minutes'), |
||
| 95 | amPmBlock = popover.find('.clockpicker-am-pm-block'), |
||
| 96 | isInput = element.prop('tagName') === 'INPUT', |
||
| 97 | input = isInput ? element : element.find('input'), |
||
| 98 | addon = element.find('.input-group-addon'), |
||
| 99 | self = this, |
||
| 100 | timer; |
||
|
|
|||
| 101 | |||
| 102 | this.id = uniqueId('cp'); |
||
| 103 | this.element = element; |
||
| 104 | this.options = options; |
||
| 105 | this.isAppended = false; |
||
| 106 | this.isShown = false; |
||
| 107 | this.currentView = 'hours'; |
||
| 108 | this.isInput = isInput; |
||
| 109 | this.input = input; |
||
| 110 | this.addon = addon; |
||
| 111 | this.popover = popover; |
||
| 112 | this.plate = plate; |
||
| 113 | this.hoursView = hoursView; |
||
| 114 | this.minutesView = minutesView; |
||
| 115 | this.amPmBlock = amPmBlock; |
||
| 116 | this.spanHours = popover.find('.clockpicker-span-hours'); |
||
| 117 | this.spanMinutes = popover.find('.clockpicker-span-minutes'); |
||
| 118 | this.spanAmPm = popover.find('.clockpicker-span-am-pm'); |
||
| 119 | this.amOrPm = "PM"; |
||
| 120 | |||
| 121 | // Setup for for 12 hour clock if option is selected |
||
| 122 | if (options.twelvehour) { |
||
| 123 | |||
| 124 | var amPmButtonsTemplate = ['<div class="clockpicker-am-pm-block">', |
||
| 125 | '<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-am-button">', |
||
| 126 | 'AM</button>', |
||
| 127 | '<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-pm-button">', |
||
| 128 | 'PM</button>', |
||
| 129 | '</div>'].join(''); |
||
| 130 | |||
| 131 | var amPmButtons = $(amPmButtonsTemplate); |
||
| 132 | //amPmButtons.appendTo(plate); |
||
| 133 | |||
| 134 | ////Not working b/c they are not shown when this runs |
||
| 135 | //$('clockpicker-am-button') |
||
| 136 | // .on("click", function() { |
||
| 137 | // self.amOrPm = "AM"; |
||
| 138 | // $('.clockpicker-span-am-pm').empty().append('AM'); |
||
| 139 | // }); |
||
| 140 | // |
||
| 141 | //$('clockpicker-pm-button') |
||
| 142 | // .on("click", function() { |
||
| 143 | // self.amOrPm = "PM"; |
||
| 144 | // $('.clockpicker-span-am-pm').empty().append('PM'); |
||
| 145 | // }); |
||
| 146 | |||
| 147 | $('<button type="button" class="btn btn-sm btn-default clockpicker-button am-button">' + "AM" + '</button>') |
||
| 148 | .on("click", function() { |
||
| 149 | self.amOrPm = "AM"; |
||
| 150 | $('.clockpicker-span-am-pm').empty().append('AM'); |
||
| 151 | }).appendTo(this.amPmBlock); |
||
| 152 | |||
| 153 | |||
| 154 | $('<button type="button" class="btn btn-sm btn-default clockpicker-button pm-button">' + "PM" + '</button>') |
||
| 155 | .on("click", function() { |
||
| 156 | self.amOrPm = 'PM'; |
||
| 157 | $('.clockpicker-span-am-pm').empty().append('PM'); |
||
| 158 | }).appendTo(this.amPmBlock); |
||
| 159 | |||
| 160 | } |
||
| 161 | |||
| 162 | if (! options.autoclose) { |
||
| 163 | // If autoclose is not setted, append a button |
||
| 164 | $('<button type="button" class="btn btn-sm btn-default btn-block clockpicker-button">' + options.donetext + '</button>') |
||
| 165 | .click($.proxy(this.done, this)) |
||
| 166 | .appendTo(popover); |
||
| 167 | } |
||
| 168 | |||
| 169 | // Placement and arrow align - make sure they make sense. |
||
| 170 | if ((options.placement === 'top' || options.placement === 'bottom') && (options.align === 'top' || options.align === 'bottom')) options.align = 'left'; |
||
| 171 | if ((options.placement === 'left' || options.placement === 'right') && (options.align === 'left' || options.align === 'right')) options.align = 'top'; |
||
| 172 | |||
| 173 | popover.addClass(options.placement); |
||
| 174 | popover.addClass('clockpicker-align-' + options.align); |
||
| 175 | |||
| 176 | this.spanHours.click($.proxy(this.toggleView, this, 'hours')); |
||
| 177 | this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes')); |
||
| 178 | |||
| 179 | // Show or toggle |
||
| 180 | input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this)); |
||
| 181 | addon.on('click.clockpicker', $.proxy(this.toggle, this)); |
||
| 182 | |||
| 183 | // Build ticks |
||
| 184 | var tickTpl = $('<div class="clockpicker-tick"></div>'), |
||
| 185 | i, tick, radian, radius; |
||
| 186 | |||
| 187 | // Hours view |
||
| 188 | if (options.twelvehour) { |
||
| 189 | for (i = 1; i < 13; i += 1) { |
||
| 190 | tick = tickTpl.clone(); |
||
| 191 | radian = i / 6 * Math.PI; |
||
| 192 | radius = outerRadius; |
||
| 193 | tick.css('font-size', '120%'); |
||
| 194 | tick.css({ |
||
| 195 | left: dialRadius + Math.sin(radian) * radius - tickRadius, |
||
| 196 | top: dialRadius - Math.cos(radian) * radius - tickRadius |
||
| 197 | }); |
||
| 198 | tick.html(i === 0 ? '00' : i); |
||
| 199 | hoursView.append(tick); |
||
| 200 | tick.on(mousedownEvent, mousedown); |
||
| 201 | } |
||
| 202 | } else { |
||
| 203 | for (i = 0; i < 24; i += 1) { |
||
| 204 | tick = tickTpl.clone(); |
||
| 205 | radian = i / 6 * Math.PI; |
||
| 206 | var inner = i > 0 && i < 13; |
||
| 207 | radius = inner ? innerRadius : outerRadius; |
||
| 208 | tick.css({ |
||
| 209 | left: dialRadius + Math.sin(radian) * radius - tickRadius, |
||
| 210 | top: dialRadius - Math.cos(radian) * radius - tickRadius |
||
| 211 | }); |
||
| 212 | if (inner) { |
||
| 213 | tick.css('font-size', '120%'); |
||
| 214 | } |
||
| 215 | tick.html(i === 0 ? '00' : i); |
||
| 216 | hoursView.append(tick); |
||
| 217 | tick.on(mousedownEvent, mousedown); |
||
| 218 | } |
||
| 219 | } |
||
| 220 | |||
| 221 | // Minutes view |
||
| 222 | for (i = 0; i < 60; i += 5) { |
||
| 223 | tick = tickTpl.clone(); |
||
| 224 | radian = i / 30 * Math.PI; |
||
| 225 | tick.css({ |
||
| 226 | left: dialRadius + Math.sin(radian) * outerRadius - tickRadius, |
||
| 227 | top: dialRadius - Math.cos(radian) * outerRadius - tickRadius |
||
| 228 | }); |
||
| 229 | tick.css('font-size', '120%'); |
||
| 230 | tick.html(leadingZero(i)); |
||
| 231 | minutesView.append(tick); |
||
| 232 | tick.on(mousedownEvent, mousedown); |
||
| 233 | } |
||
| 234 | |||
| 235 | // Clicking on minutes view space |
||
| 236 | plate.on(mousedownEvent, function(e){ |
||
| 237 | if ($(e.target).closest('.clockpicker-tick').length === 0) { |
||
| 238 | mousedown(e, true); |
||
| 239 | } |
||
| 240 | }); |
||
| 241 | |||
| 242 | // Mousedown or touchstart |
||
| 243 | function mousedown(e, space) { |
||
| 244 | var offset = plate.offset(), |
||
| 245 | isTouch = /^touch/.test(e.type), |
||
| 246 | x0 = offset.left + dialRadius, |
||
| 247 | y0 = offset.top + dialRadius, |
||
| 248 | dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, |
||
| 249 | dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0, |
||
| 250 | z = Math.sqrt(dx * dx + dy * dy), |
||
| 251 | moved = false; |
||
| 252 | |||
| 253 | // When clicking on minutes view space, check the mouse position |
||
| 254 | if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius)) { |
||
| 255 | return; |
||
| 256 | } |
||
| 257 | e.preventDefault(); |
||
| 258 | |||
| 259 | // Set cursor style of body after 200ms |
||
| 260 | var movingTimer = setTimeout(function(){ |
||
| 261 | $body.addClass('clockpicker-moving'); |
||
| 262 | }, 200); |
||
| 263 | |||
| 264 | // Place the canvas to top |
||
| 265 | if (svgSupported) { |
||
| 266 | plate.append(self.canvas); |
||
| 267 | } |
||
| 268 | |||
| 269 | // Clock |
||
| 270 | self.setHand(dx, dy, ! space, true); |
||
| 271 | |||
| 272 | // Mousemove on document |
||
| 273 | $doc.off(mousemoveEvent).on(mousemoveEvent, function(e){ |
||
| 274 | e.preventDefault(); |
||
| 275 | var isTouch = /^touch/.test(e.type), |
||
| 276 | x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, |
||
| 277 | y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0; |
||
| 278 | if (! moved && x === dx && y === dy) { |
||
| 279 | // Clicking in chrome on windows will trigger a mousemove event |
||
| 280 | return; |
||
| 281 | } |
||
| 282 | moved = true; |
||
| 283 | self.setHand(x, y, false, true); |
||
| 284 | }); |
||
| 285 | |||
| 286 | // Mouseup on document |
||
| 287 | $doc.off(mouseupEvent).on(mouseupEvent, function(e){ |
||
| 288 | $doc.off(mouseupEvent); |
||
| 289 | e.preventDefault(); |
||
| 290 | var isTouch = /^touch/.test(e.type), |
||
| 291 | x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0, |
||
| 292 | y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0; |
||
| 293 | if ((space || moved) && x === dx && y === dy) { |
||
| 294 | self.setHand(x, y); |
||
| 295 | } |
||
| 296 | if (self.currentView === 'hours') { |
||
| 297 | self.toggleView('minutes', duration / 2); |
||
| 298 | } else { |
||
| 299 | if (options.autoclose) { |
||
| 300 | self.minutesView.addClass('clockpicker-dial-out'); |
||
| 301 | setTimeout(function(){ |
||
| 302 | self.done(); |
||
| 303 | }, duration / 2); |
||
| 304 | } |
||
| 305 | } |
||
| 306 | plate.prepend(canvas); |
||
| 307 | |||
| 308 | // Reset cursor style of body |
||
| 309 | clearTimeout(movingTimer); |
||
| 310 | $body.removeClass('clockpicker-moving'); |
||
| 311 | |||
| 312 | // Unbind mousemove event |
||
| 313 | $doc.off(mousemoveEvent); |
||
| 314 | }); |
||
| 315 | } |
||
| 316 | |||
| 317 | if (svgSupported) { |
||
| 318 | // Draw clock hands and others |
||
| 319 | var canvas = popover.find('.clockpicker-canvas'), |
||
| 320 | svg = createSvgElement('svg'); |
||
| 321 | svg.setAttribute('class', 'clockpicker-svg'); |
||
| 322 | svg.setAttribute('width', diameter); |
||
| 323 | svg.setAttribute('height', diameter); |
||
| 324 | var g = createSvgElement('g'); |
||
| 325 | g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); |
||
| 326 | var bearing = createSvgElement('circle'); |
||
| 327 | bearing.setAttribute('class', 'clockpicker-canvas-bearing'); |
||
| 328 | bearing.setAttribute('cx', 0); |
||
| 329 | bearing.setAttribute('cy', 0); |
||
| 330 | bearing.setAttribute('r', 2); |
||
| 331 | var hand = createSvgElement('line'); |
||
| 332 | hand.setAttribute('x1', 0); |
||
| 333 | hand.setAttribute('y1', 0); |
||
| 334 | var bg = createSvgElement('circle'); |
||
| 335 | bg.setAttribute('class', 'clockpicker-canvas-bg'); |
||
| 336 | bg.setAttribute('r', tickRadius); |
||
| 337 | var fg = createSvgElement('circle'); |
||
| 338 | fg.setAttribute('class', 'clockpicker-canvas-fg'); |
||
| 339 | fg.setAttribute('r', 3.5); |
||
| 340 | g.appendChild(hand); |
||
| 341 | g.appendChild(bg); |
||
| 342 | g.appendChild(fg); |
||
| 343 | g.appendChild(bearing); |
||
| 344 | svg.appendChild(g); |
||
| 345 | canvas.append(svg); |
||
| 346 | |||
| 347 | this.hand = hand; |
||
| 348 | this.bg = bg; |
||
| 349 | this.fg = fg; |
||
| 350 | this.bearing = bearing; |
||
| 351 | this.g = g; |
||
| 352 | this.canvas = canvas; |
||
| 353 | } |
||
| 354 | |||
| 355 | raiseCallback(this.options.init); |
||
| 356 | } |
||
| 357 | |||
| 730 |